package com.future.wxapp.pedometer.schedule;

import com.future.wxapp.pedometer.dao.*;
import com.future.wxapp.pedometer.data.Address;
import com.future.wxapp.pedometer.domain.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xd
 */
@Configuration
@EnableScheduling
@Slf4j
public class InitDataSchedule {
    @Autowired
    private ChickenDao chickenDao;
    @Autowired
    private BatchesDao batchesDao;
    @Autowired
    private TypeDao typeDao;
    @Autowired
    private StepNumberDao stepDao;
    @Autowired
    private SellDao sellDao;
    @Autowired
    private Address address;


    private String cron = "0 0 0/3 * * ?";

    //cron 每三个小时执行一次
    @Scheduled(cron = "0 0 0 * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void scheduledTask() {
        Calendar calendar = Calendar.getInstance();
        Date date = calendar.getTime();
        log.info("当前时间为:{}", DateFormatUtils.format(date, "yyyy-MM-dd HH:mm:ss"));

        //模拟插入数据
        for (Type type : typeDao.selectAll()) {
            Batches batches = new Batches();
            batches.setBirthday(new Date());
            batches.setType(type.getId());
            batches.setAddress(address.getRandomAddress());
            batches.setBirthday(date);
            batches.setTypeName(type.getTypeName());
            //设置出生时间
            calendar.add(Calendar.DATE, -(new Random().nextInt(8)));
            batches.setBirthday(calendar.getTime());

            //设置上环时间
            calendar.add(Calendar.DATE, new Random().nextInt(8));
            batches.setMarkDate(calendar.getTime());

            batches.setCreateTime(date);

            //数量
            batches.setNumber(new Random().nextInt(100));
            batchesDao.insertUseGeneratedKeys(batches);

            List<Chicken> chickenList = new ArrayList<>();
            for (int i = 0; i < batches.getNumber(); i++) {
                Chicken chicken = new Chicken();
                chicken.setBatchesId(batches.getBatchesId());
                chicken.setSex((byte) new Random().nextInt(2));
                chicken.setCreateTime(date);
                chicken.setType(type.getId());
                chicken.setWeight(BigDecimal.valueOf(getRandomWeight(1, 0.1)));
                chickenList.add(chicken);
            }
            chickenDao.insertList(chickenList);

        }
    }


    @Scheduled(cron = "0 0 0 * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void insertStep() {
        Date date = new Date();
        List<StepNumber> stepNumbers = new ArrayList<>();
        for (Long id : chickenDao.selectAll().stream().map(Chicken::getChickenId).collect(Collectors.toList())) {
            StepNumber stepNumber = new StepNumber();
            stepNumber.setChickenId(Math.toIntExact(id));
            stepNumber.setCreateTime(date);
            stepNumber.setStep(new Random().nextInt(2000));
            stepNumbers.add(stepNumber);
        }
        stepDao.insertList(stepNumbers);

    }

    @Scheduled(cron = "0 0 0 * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void insertSell() {
        Date date = new Date();
        List<Long> chickenIds = chickenDao.selectAll().stream().map(Chicken::getChickenId).collect(Collectors.toList());
        List<Long> alreadySellIds = sellDao.selectAll().stream().map(sell -> sell.getChickenId().longValue()).collect(Collectors.toList());
        chickenIds.removeAll(alreadySellIds);

        if (chickenIds.size() > 100) {
            int sellNumber = new Random().nextInt(50);
            List<Sell> sellList = new ArrayList<>();
            for (int i = 0; i < sellNumber; i++) {
                Sell sell = new Sell();
                sell.setPrice(getRandomPrice(50, 100));
                sell.setSellTime(date);
                Long id = chickenIds.get(new Random().nextInt(chickenIds.size()));
                sell.setChickenId(Math.toIntExact(id));
                chickenIds.remove(id);
                sellList.add(sell);
            }

            sellDao.insertList(sellList);
        }

    }

    private static double getRandomWeight(double maxWeight, double minWeight) {
        double weight = Math.random();
        if (weight < minWeight || weight > maxWeight) {
            weight = getRandomWeight(maxWeight, minWeight);
        }
        return weight;
    }

    private static double getRandomPrice(double min, double max) {
        double price = Math.random() * (max - min) + min;
        if (price < min || price > max) {
            price = getRandomPrice(min, max);
        }
        return price;
    }


}
